home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1995 November
/
EnigmA AMIGA RUN 02 (1995)(G.R. Edizioni)(IT)[!][issue 1995-11][Skylink CD].iso
/
earcd
/
program
/
misc
/
iedit210.lha
/
IEditor
/
Examples
/
MemoryObserver
/
MemoryObs.s
< prev
Wrap
Text File
|
1995-06-24
|
10KB
|
467 lines
**************************************************************************
* *
* Memory Observer - ©1995 Simone Tellini Software *
* *
* 13/06/95 First Version by Simone Tellini *
* *
* Feel free to modify (and improve ;) this source, but please *
* leave my name in it! - Thanks, Simone *
* *
**************************************************************************
opt ! ; for PhxAss: all optimizations on
incdir /include/
include dos/dos_lib.i
include exec/exec_lib.i
include exec/nodes.i
include intuition/intuition.i
include intuition/intuition_lib.i
include gadtools_lib.i
include libraries/gadtools.i
include mymacros.i
include sources/mo/MemoryObs_gui.i
SECTION MemObserver,CODE
include iconstartup.i ; let us start from WB
move.l 4,a6 ; let's open some libs...
openlib dos,0,exit
openlib gad,0,closedos
openlib int,0,closegad
call CreateMsgPort ; for timer.device's messages
move.l d0,timerport
beq closeint
move.l d0,a0
move.b MP_SIGBIT(a0),d1
moveq #1,d0
lsl.l d1,d0
move.l d0,bitmask
move.l d0,timermask
move.l #IOTV_SIZE,d0
call CreateIORequest
move.l d0,timerreq
beq deleteport
move.l d0,a1 ; open the timer device
move.w #TR_ADDREQUEST,IO_COMMAND(a1)
move.l #20,IO_SIZE+TV_MICRO(a1)
lea timer_name(pc),a0
moveq #UNIT_VBLANK,d0 ; 1/50 sec is what I need
cldat d1
call OpenDevice
tst.l d0
bne deletereq
* I call the routines of the module MemoryObs_gui.o with 'bsr', so
* I _MUST_ link the two modules together with the SmallCode parameter.
bsr SetupScreen ; lock it & get VisualInfos
tst.l d0 ; success?
bne closescr ; nope...
move.l Scr,a0 ; compute the value for the
move.b sc_WBorTop(a0),d0 ; height of the window
ext.w d0 ; "zipped"
inc.w d0 ; height = sc_WBorTop + Font.ta_YSize + 1
move.l sc_Font(a0),a0
add.w ta_YSize(a0),d0
move.w d0,MainZoom+6
sub.w #10,d0 ; fit the height of the window
lea MainWTags,a0 ; to the height of the screen font
add.w d0,WT_HEIGHT(a0)
bsr OpenMainWindow ; open my window
tst.l d0
bne closewnd
move.l MainWnd,a0 ; get its signal bit...
move.l wd_UserPort(a0),a0
move.b MP_SIGBIT(a0),d1
moveq #1,d0
lsl.l d1,d0
or.l d0,bitmask ; ...and join it with the timer's one
move.l timerreq,a1 ; start the timer
call SendIO
mainloop move.l 4,a6 ; wait for a signal
move.l bitmask,d0
call Wait
move.l timermask,d1 ; is it the timer that calls? :)
and.l d0,d1
beq.s .notimer ; nope...
btst #MONITOR,flags ; we should monitor the
beq.s .nomon ; memory?
move.l address,a0
move.w size+2(pc),d1
cmp.w #2,d1 ; if we aren't monitoring
beq.s .noround ; a single byte, we must
move.l a0,d0 ; round to an even address
and.l #~1,d0
move.l d0,a0
.noround cldat d0
lea size_routines(pc),a1
add.w d1,d1
add.w d1,d1
move.l 0(a1,d1.w),a1
jsr (a1) ; get the value!
move.l d0,d7
cmp.l last,d0 ; did it change since last read?
beq.s .nomon
btst #_BEEP,flags ; is the beeper active?
beq.s .nobeep
beep ; a simple but useful macro ;-)
.nobeep move.l d7,hex
move.l HexGadget,a0 ; update the displays...
lea hex_tag(pc),a3
bsr SetTag
move.l DecGadget,a0
lea hex_tag(pc),a3
bsr SetTag
move.l d7,last
lea last2,a0 ; Replace the 0's with
move.l d7,(a0) ; a space, so the gadget
moveq #3,d0 ; displays all the bytes
.search tst.b (a0)+ ; I want it to...
bne.s .next
move.b #' ',-1(a0)
.next dbra d0,.search
move.l AscGadget,a0
lea asc_tag(pc),a3
bsr SetTag
bsr Binary
.nomon move.l 4,a6 ; re-start timer...
move.l timerreq,a1
add.l #20,IO_SIZE+TV_MICRO(a1)
call SendIO
.notimer bsr HandleMainIDCMP ; check messages from the window
btst #QUIT,flags ; should we quit?
beq mainloop
closewnd bsr CloseMainWindow
closescr bsr CloseDownScreen ; unlock & free vi
closetimer move.l 4,a6 ; close timer.device
move.l timerreq,a1
call CloseDevice
deletereq move.l 4,a6 ; delete the io request
move.l timerreq,a0
call DeleteIORequest
deleteport move.l 4,a6 ; delete the msg port
move.l timerport,a0
call DeleteMsgPort
closeint closelib int ; close all the libs
closegad closelib gad
closedos closelib dos
exit rts
SetTag move.l gad_base,a6 ; little sub that sets a tag... ;)
move.l MainWnd,a1
cladd a2
call GT_SetGadgetAttrsA
rts
long move.l (a0),d0
rts
word move.w (a0),d0
rts
byte move.b (a0),d0
rts
******** Routines called by HandleMainIDCMP
XDEF MainCloseWindow
MainCloseWindow bset #QUIT,flags
rts
XDEF MainVanillaKey
MainVanillaKey move.w im_Code(a5),d5 ; a5 = ^IntuiMsg
cmp.b #$20,d5
blt.s .raw
cmp.b #$7E,d5
bgt.s .raw
or.b #$20,d5 ; lowercase
.raw moveq #KEYS-1,d1
move.w d1,d0
lea keytable(pc),a0
.search cmp.b (a0)+,d5 ; search the key in the table
dbeq d1,.search
tst.w d1 ; found?
bge.s .ok ; yes!
rts ; do nothing.
.ok sub.w d1,d0 ; get the right function...
lsl.w #2,d0
lea funtable(pc),a0
move.l 0(a0,d0.w),a0
jmp (a0) ; ...and execute it!
XDEF MonClicked
MonClicked lea checked_tag(pc),a3 ; toggle the check
bchg #MONITOR,flags
seq 7(a3)
move.l MonGadget,a0
move.l a3,a4
bra SetTag
XDEF BeepClicked
BeepClicked lea checked_tag(pc),a3
bchg #_BEEP,flags
seq 7(a3)
move.l BeepGadget,a0
bra SetTag
XDEF SignClicked
SignClicked lea checked_tag(pc),a3
bchg #SIGN,flags
seq 7(a3)
move.l SignGadget,a0
move.l a3,a4
bsr SetTag
tst.b 7(a4) ; if checked...
beq.s .unsigned
move.b #'d',sign ; ...set the "d" fmt type...
bra.s .ok
.unsigned move.b #'u',sign ; ...else set the "u"
.ok move.l DecGadget,a0
lea format_tag(pc),a3
move.l #FormatStr,4(a3)
bra SetTag
XDEF AdrClicked
AdrClicked move.l AdrGadget,a0
move.l gg_SpecialInfo(a0),a0
move.l si_Buffer(a0),a0
moveq #0,d1
push.l a0
.search_end tst.b (a0)+ ; count chars
beq.s .found
inc.w d1
bra.s .search_end
.found pop.l a0
move.b d1,d3 ; store it
lsr.w #1,d1 ; divide by 2
lea address,a1
clr.l (a1) ; clear the address
moveq #4,d2 ; how many bytes shall we skip?
sub.b d1,d2
add.l d2,a1
dec.w d1 ; because of dbra
and.b #1,d3 ; the number of chars is even?
beq.s .loop ; yes, alright!
inc.w d1 ; no, there's a lone nibble...
cldat d2
dec.l a1
bra.s .secondnibble
.loop move.b (a0)+,d0 ; get the first nibble
bsr.s ConvertNibble ; convert it
move.b d0,d2 ; store it
.secondnibble move.b (a0)+,d0 ; get the second nibble
bsr.s ConvertNibble ; convert it
lsl.b #4,d2 ; a little shift... (e.g. 0f -> f0)
or.b d2,d0 ; join the nibbles (e.g. f0 0f -> ff)
move.b d0,(a1)+ ; store the number
dbra d1,.loop ; let's do it again! ;)
rts
ConvertNibble cmp.b #'0',d0 ; is it between '0' and '9'?
blt.s .error
cmp.b #'9',d0
bgt.s .hex
sub.b #'0',d0 ; ok, transform to binary
rts
.hex or.b #$20,d0 ; lovercase
cmp.b #'a',d0 ; is it between 'a' and 'f'?
blt.s .error
cmp.b #'f',d0
bgt.s .error
sub.b #'a'-10,d0 ; ok, trasform to binary
rts
.error beep
addq.l #4,sp ; remove the return address of
rts ; the call so to return to mainloop
XDEF SizeClicked
SizeClicked lea size_tag(pc),a3
move.w im_Code(a5),6(a3)
move.l SizeGadget,a0
bsr SetTag
lea setsize_routines(pc),a0
move.w im_Code(a5),d0
add.w d0,d0
add.w d0,d0
move.l 0(a0,d0.w),a0
jmp (a0)
LClicked clr.w size+2
move.l SizeGadget,a0
lea size_tag(pc),a3
bsr SetTag
bra.s SetLong
WClicked move.w #1,size+2
move.l SizeGadget,a0
lea size_tag(pc),a3
bsr SetTag
bra.s SetWord
BClicked move.w #2,size+2
move.l SizeGadget,a0
lea size_tag(pc),a3
bsr SetTag
SetByte lea format_tag(pc),a3 ; these routines change the
move.l #FmtByteHex,4(a3) ; /look/ of the gadgets... :)
move.l HexGadget,a0
bsr SetTag
move.l AscGadget,a0
lea asc_tag(pc),a3
move.l #last2+3,4(a3)
bsr SetTag
bra.s Binary
SetLong lea format_tag(pc),a3
move.l #FmtLongHex,4(a3)
move.l HexGadget,a0
bsr SetTag
move.l AscGadget,a0
lea asc_tag(pc),a3
move.l #last2,4(a3)
bsr SetTag
bra.s Binary
SetWord lea format_tag(pc),a3
move.l #FmtWordHex,4(a3)
move.l HexGadget,a0
bsr SetTag
move.l AscGadget,a0
lea asc_tag(pc),a3
move.l #last2+2,4(a3)
bsr SetTag
Binary move.w size+2(pc),d0 ; how many bytes must we convert?
add.w d0,d0
lea lenght(pc),a0
move.w 0(a0,d0.w),d3
moveq #4,d4
sub.w d3,d4
dec.w d4
lea bin_space,a1
move.b #'%',(a1)+
lea last,a2
add.w d4,a2 ; skip the bytes not used
.loop move.b (a2)+,d1
moveq #7,d2 ; Bits in a byte - 1
.convertloop btst d2,d1 ; it's as easy as that... :)
beq.s .zero
move.b #'1',(a1)+
bra.s .next
.zero move.b #'0',(a1)+
.next dbra d2,.convertloop
move.b #'.',(a1)+
dbra d3,.loop
clr.b -(a1)
move.l BinGadget,a0
lea bin_tag(pc),a3
bra SetTag
ActivateAdr move.l AdrGadget,a0
move.l MainWnd,a1
cladd a2
move.l int_base,a6
jmp _LVOActivateGadget(a6)
gad_name dc.b 'gadtools.library',0
int_name dc.b 'intuition.library',0
dos_name dc.b 'dos.library',0
timer_name dc.b 'timer.device',0
version dc.b '$VER: Memory_Observer 1.0 (14.6.95) by Simone Tellini',0
FormatStr dc.b '#%010l'
sign dc.b 'u',0
FmtLongHex dc.b '$%08lx',0
FmtWordHex dc.b '$%04lx',0
FmtByteHex dc.b '$%02lx',0
keytable dc.b 'm','e','s','l','w','b','a'
KEYS EQU *-keytable
cnop 0,4
funtable dc.l MonClicked,BeepClicked,SignClicked
dc.l LClicked,WClicked,BClicked
dc.l ActivateAdr
lenght dc.w 3,1,0
size_routines dc.l long,word,byte
setsize_routines dc.l SetLong,SetWord,SetByte
checked_tag dc.l GTCB_Checked,0,TAG_END
format_tag dc.l GTNM_Format,FormatStr,TAG_END
size_tag dc.l GTMX_Active
size dc.l 0,TAG_END
hex_tag dc.l GTNM_Number
hex dc.l 0,TAG_END
asc_tag dc.l GTTX_Text,last2,TAG_END
bin_tag dc.l GTTX_Text,bin_space,TAG_END
SECTION MemObserver_DataSpace,BSS
XDEF gad_base
XDEF int_base
gad_base ds.l 1
dos_base ds.l 1
int_base ds.l 1
timerport ds.l 1
timerreq ds.l 1
bitmask ds.l 1
timermask ds.l 1
address ds.l 1
last ds.l 1
last2 ds.l 1 ; for the ASCII text gadget
ds.b 1 ; end of string
bin_space ds.b (4*8)+5
flags ds.b 1
QUIT EQU 0 ; flags bits
MONITOR EQU 1
SIGN EQU 2
_BEEP EQU 3
END